﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Markup;
using System.Windows.Media;

namespace FasterWPF
{
    public static class ButtonExt
    {
        public static void ApplyButtonStrategy(this Button btn, string buttonBackground, string buttonBorderBrush, string mouseOverHighlightColor, string mouseOverBorderColor, string pressedColor, string pressedBorderColor, Thickness buttonPadding, VerticalAlignment contentVertAlignment, HorizontalAlignment contentHorizAlignment)
        {
            string xaml = "<ControlTemplate TargetType=\"{x:Type ButtonBase}\"><theme:ButtonChrome Name=\"Chrome\"        Background=\"" + buttonBackground + "\" BorderBrush=\"" + buttonBorderBrush + "\" RenderDefaulted=\"{TemplateBinding Button.IsDefaulted}\" RenderMouseOver=\"{TemplateBinding IsMouseOver}\" RenderPressed=\"{TemplateBinding IsPressed}\" SnapsToDevicePixels=\"true\"><ContentPresenter Margin=\"" + buttonPadding + "\"  VerticalAlignment=\"" + contentVertAlignment + "\" HorizontalAlignment=\"" + contentHorizAlignment + "\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\"/></theme:ButtonChrome><ControlTemplate.Triggers><Trigger Property=\"IsMouseOver\" Value=\"true\"><Setter TargetName=\"Chrome\" Property=\"RenderMouseOver\" Value=\"false\"/><Setter TargetName=\"Chrome\" Property=\"BorderBrush\" Value=\"" + mouseOverBorderColor + "\"/><Setter TargetName=\"Chrome\" Property=\"Background\" Value=\"" + mouseOverHighlightColor + "\"/></Trigger><Trigger Property=\"IsKeyboardFocused\" Value=\"true\"><Setter TargetName=\"Chrome\" Property=\"RenderDefaulted\" Value=\"false\"/><Setter TargetName=\"Chrome\" Property=\"BorderBrush\" Value=\"" + pressedBorderColor + "\"/><Setter TargetName=\"Chrome\" Property=\"Background\" Value=\"" + pressedColor + "\"/></Trigger><Trigger Property=\"ToggleButton.IsChecked\" Value=\"true\"><Setter TargetName=\"Chrome\" Property=\"RenderPressed\" Value=\"false\"/><Setter TargetName=\"Chrome\" Property=\"BorderBrush\" Value=\"" + pressedBorderColor + "\"/><Setter TargetName=\"Chrome\" Property=\"Background\" Value=\"" + pressedColor + "\"/></Trigger><Trigger Property=\"IsEnabled\" Value=\"false\"><Setter Property=\"Foreground\" Value=\"#ADADAD\"/></Trigger><Trigger Property=\"IsPressed\"        Value=\"true\"><Setter TargetName=\"Chrome\" Property=\"RenderPressed\" Value=\"false\"/><Setter TargetName=\"Chrome\" Property=\"BorderBrush\" Value=\"" + pressedBorderColor + "\"/><Setter TargetName=\"Chrome\" Property=\"Background\" Value=\"" + pressedColor + "\"/></Trigger></ControlTemplate.Triggers></ControlTemplate>";

                MemoryStream sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
                ParserContext pc = new ParserContext();
                pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
                pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
                pc.XmlnsDictionary.Add("theme", "clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero");
                var btnTemplate = (ControlTemplate)XamlReader.Load(sr, pc);
                btn.Template = btnTemplate;
        }

        public static void ApplyButtonStrategy(this Button btn, string gradientStop1Color, string gradientStop2Color, string gradientStop3Color, string gradientStop4Color, string buttonBorderBrush, string gradientMouseOver1Color, string gradientMouseOver2Color, string gradientMouseOver3Color, string gradientMouseOver4Color, string mouseOverBorderColor, string gradientPressed1Color, string gradientPressed2Color, string gradientPressed3Color, string gradientPressed4Color, string pressedBorderColor, Thickness buttonPadding, VerticalAlignment contentVertAlignment, HorizontalAlignment contentHorizAlignment)
        {
            string res1 = "<LinearGradientBrush  x:Key=\"MyBrush\" StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientStop Offset=\"0\" Color=\"" + gradientStop1Color + "\"/><GradientStop Offset=\"0.49\" Color=\"" + gradientStop2Color + "\"/><GradientStop Offset=\"0.50\" Color=\"" + gradientStop3Color + "\" /><GradientStop Offset=\"1\" Color=\"" + gradientStop4Color + "\"/></LinearGradientBrush>";

            string res2 = "<LinearGradientBrush  x:Key=\"MyMouseOverBrush\" StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientStop Offset=\"0\" Color=\"" + gradientMouseOver1Color + "\"/><GradientStop Offset=\"0.49\" Color=\"" + gradientMouseOver2Color + "\"/><GradientStop Offset=\"0.50\" Color=\"" + gradientMouseOver3Color + "\" /><GradientStop Offset=\"1\" Color=\"" + gradientMouseOver4Color + "\"/></LinearGradientBrush>";

            string res3 = "<LinearGradientBrush  x:Key=\"MyPressedBrush\" StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientStop Offset=\"0\" Color=\"" + gradientPressed1Color + "\"/><GradientStop Offset=\"0.49\" Color=\"" + gradientPressed2Color + "\"/><GradientStop Offset=\"0.50\" Color=\"" + gradientPressed3Color + "\" /><GradientStop Offset=\"1\" Color=\"" + gradientPressed4Color + "\"/></LinearGradientBrush>";

            string xaml = "<ControlTemplate TargetType=\"{x:Type ButtonBase}\"><ControlTemplate.Resources>" + res1 + res2 + res3 + "</ControlTemplate.Resources><theme:ButtonChrome Name=\"Chrome\"        Background=\"{StaticResource MyBrush}\" BorderBrush=\"" + buttonBorderBrush + "\" RenderDefaulted=\"{TemplateBinding Button.IsDefaulted}\" RenderMouseOver=\"{TemplateBinding IsMouseOver}\" RenderPressed=\"{TemplateBinding IsPressed}\" SnapsToDevicePixels=\"true\"><ContentPresenter Margin=\"" + buttonPadding + "\"  VerticalAlignment=\"" + contentVertAlignment + "\" HorizontalAlignment=\"" + contentHorizAlignment + "\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\"/></theme:ButtonChrome><ControlTemplate.Triggers><Trigger Property=\"IsMouseOver\" Value=\"true\"><Setter TargetName=\"Chrome\" Property=\"RenderMouseOver\" Value=\"false\"/><Setter TargetName=\"Chrome\" Property=\"BorderBrush\" Value=\"" + mouseOverBorderColor + "\"/><Setter TargetName=\"Chrome\" Property=\"Background\" Value=\"{StaticResource MyMouseOverBrush}\"/></Trigger><Trigger Property=\"IsKeyboardFocused\" Value=\"true\"><Setter TargetName=\"Chrome\" Property=\"RenderDefaulted\" Value=\"false\"/><Setter TargetName=\"Chrome\" Property=\"BorderBrush\" Value=\"" + pressedBorderColor + "\"/><Setter TargetName=\"Chrome\" Property=\"Background\" Value=\"{StaticResource MyPressedBrush}\"/></Trigger><Trigger Property=\"ToggleButton.IsChecked\" Value=\"true\"><Setter TargetName=\"Chrome\" Property=\"RenderPressed\" Value=\"false\"/><Setter TargetName=\"Chrome\" Property=\"BorderBrush\" Value=\"" + pressedBorderColor + "\"/><Setter TargetName=\"Chrome\" Property=\"Background\" Value=\"{StaticResource MyPressedBrush}\"/></Trigger><Trigger Property=\"IsEnabled\" Value=\"false\"><Setter Property=\"Foreground\" Value=\"#ADADAD\"/></Trigger><Trigger Property=\"IsPressed\"        Value=\"true\"><Setter TargetName=\"Chrome\" Property=\"RenderPressed\" Value=\"false\"/><Setter TargetName=\"Chrome\" Property=\"BorderBrush\" Value=\"" + pressedBorderColor + "\"/><Setter TargetName=\"Chrome\" Property=\"Background\" Value=\"{StaticResource MyPressedBrush}\"/></Trigger></ControlTemplate.Triggers></ControlTemplate>";

            MemoryStream sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
            ParserContext pc = new ParserContext();
            pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
            pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
            pc.XmlnsDictionary.Add("theme", "clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero");
            var btnTemplate = (ControlTemplate)XamlReader.Load(sr, pc);
            btn.Template = btnTemplate;
        }
        
        public static Button SetBackgroundColor(this Button chain, Brush brush)
        {
            Brush newBrush = (brush);
            chain.Background = newBrush;
            return chain;
        }

        /// <summary>
        /// Initialize a Button control.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="containerType"></param>
        /// <returns></returns>
        public static Button Initialize(this Button source, double width, double height, ContainerType containerType)
        {   
            //Force the Aero theme by default to assure the structure of the Listbox
            Uri uri = new Uri("/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml", UriKind.Relative);
            source.Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);

            source.Width = width;
            source.Height = height;
            source.SetContainerType(containerType);
            IComposite icomp = CompositeTypeHelper.CreateIComposite<Button>(source);
            source.SetIComposite<Button>(icomp);

            //STORE SETTING BUILD CHAIN AND GET CHAIN?!?  Put these in a Composite implements an interface
            ButtonParent gbsr = new ButtonParent();
            source.StoreSetting<Button>("IParent", gbsr);

            source.AddItemBorder(Brushes.Gray, new Thickness(1, 1, 1, 1)); //default Border     
            source.StoreSetting<Button>("BorderSettings", new BorderSettings() { Width = double.NaN, Height = double.NaN, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(0, 0, 0, 0), CornerRadius = new CornerRadius(0), Padding = new Thickness(0) });

            return source;
        }
        
        /// <summary>
        /// Initialize a Button control applying Brushes for Normal, OnMouseOver, and Pressed.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="containerType"></param>
        /// <returns></returns>
        public static Button Initialize(this Button source, double width, double height, ContainerType containerType, string buttonBackground, string buttonBorderBrush, string mouseOverHighlightColor, string mouseOverBorderColor, string pressedColor, string pressedBorderColor, Thickness buttonPadding, VerticalAlignment contentVertAlignment, HorizontalAlignment contentHorizAlignment)
        {
            //Force the Aero theme by default to assure the structure of the Listbox
            Uri uri = new Uri("/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml", UriKind.Relative);
            source.Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);

            source.Width = width;
            source.Height = height;
            source.SetContainerType(containerType);
            IComposite icomp = CompositeTypeHelper.CreateIComposite<Button>(source);
            source.SetIComposite<Button>(icomp);

            //STORE SETTING BUILD CHAIN AND GET CHAIN?!?  Put these in a Composite implements an interface
            ButtonParent gbsr = new ButtonParent();
            source.StoreSetting<Button>("IParent", gbsr);

            source.AddItemBorder(Brushes.Gray, new Thickness(1, 1, 1, 1)); //default Border     
            source.StoreSetting<Button>("BorderSettings", new BorderSettings() { Width = double.NaN, Height = double.NaN, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(0, 0, 0, 0), CornerRadius = new CornerRadius(0), Padding = new Thickness(0) });

            source.ApplyButtonStrategy(buttonBackground, buttonBorderBrush, mouseOverHighlightColor, mouseOverBorderColor, pressedColor, pressedBorderColor, buttonPadding, contentVertAlignment, contentHorizAlignment);

            return source;
        }
        
    }//end of class
}//end of namespace
